Skip to content

fix(devx): give the last four --self-test dispatches a verdict handshake - #15729

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-15614-15657-self-test-verdict-handshake
Sep 5, 2026
Merged

fix(devx): give the last four --self-test dispatches a verdict handshake#15729
baozhoutao merged 1 commit into
mainfrom
claude/issue-15614-15657-self-test-verdict-handshake

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #15614
Fixes #15657

The last four --self-test dispatches in scripts/** discarded the self-test's
completion, so an early return yielded undefined, process.exit(undefined) was
exit 0, and the run printed zero bytes. To a CI wrapper reading only
result.status, "40 assertions held" and "the 40 assertions never ran" were the
same green. These are the measured, closed residue of the handshake programme —
165 of the census's 179 members already carry the repair.

The four sites (re-measured on this branch's base a5cef3769)

scripts/check-closing-keyword-parity.mjs:478   else if (arg === '--self-test') process.exit(selfTest());
scripts/check-pnpm-filter-targets.mjs:538      if (flag === '--self-test') process.exit(selfTest());
scripts/check-settings-bind-window.mjs:1047    if (arg === '--self-test') selfTest();
scripts/pnpm-filter-targets.mjs:695            if (flag === '--self-test') process.exit(await selfTest());

All four line numbers and spellings are verbatim as triage measured them, and each
file carried ReachedVerdict 0 occurrences (positive control: 82 files under
scripts/ carry the flag, so zero was the file's property, not the grep's).

The repair — ONE spelling, four files

A module-level selfTestReachedVerdict flag, set once a verdict has been printed
and read at the dispatch, which refuses to exit 0 without it:

✗ GATE self-test: selfTest() returned without reaching its verdict,
so no success line was printed. Exiting 0 here would report a self-test
that never finished as a self-test that passed.

The flag is set on the FAILURE path too, following the landed precedent in
scripts/check-i18n-walk-parity.mjs. Without that, a self-test that prints its
failures and returns non-zero also trips the guard and prints the
"never reached its verdict" sentence on top of a genuine red — the wart recorded on
PR #15651's ACCEPT. Here the refusal fires only when neither verdict was
printed. (check-settings-bind-window's failure path calls process.exit(1) from
inside its assert, so it has no returning failure leg to flag.)

Red/green, taken with the probe — not by eye

scripts/measure-self-test-floor.mjs's probeEarlyReturn driven against exactly
these four files, on an installed tree (an uninstalled checkout reports the
flattering answer), before and after:

script before after
scripts/check-closing-keyword-parity.mjs DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0 HELD mutatedExit=1 mutatedBytes=214 mutatedSpoke=true
scripts/check-pnpm-filter-targets.mjs DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0 HELD mutatedExit=1 mutatedBytes=211 mutatedSpoke=true
scripts/check-settings-bind-window.mjs DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0 HELD mutatedExit=1 mutatedBytes=212 mutatedSpoke=true
scripts/pnpm-filter-targets.mjs DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0 HELD mutatedExit=1 mutatedBytes=205 mutatedSpoke=true

Every AFTER row's mutatedHead is that gate's own refusal sentence, e.g.
✗ check-pnpm-filter-targets self-test: selfTest() returned without reaching its verdict,.

The assertions are untouched — verdict lines byte-identical

Captured to files before and after and compared with diff; all four reported
VERDICT LINE IDENTICAL to before, exit 0 both times:

✓ check-closing-keyword-parity --self-test: 24 assertions, 5 mutations of the shipped parsers each driven to red.
✓ check-pnpm-filter-targets --self-test: 40 assertions — a dead filter observed RED in all four carriers (workflow, package.json, shell, JS) and the same fixtures observed SILENT with a real name; 184 live occurrence(s) swept.
✓ settings bind-window guard self-test: all cases pass.
✓ pnpm-filter-targets --self-test: 54 assertions over 79 real workspace packages (match rule pinned against measured pnpm behaviour; preflight observed both REFUSING and SILENT).

Ablation, by hand, on the fixed tree

return; injected as selfTest()'s first statement in
scripts/check-pnpm-filter-targets.mjs after the fix was committed, trap-guarded,
absolute paths, mutation and restore both proven on disk:

HEAD blob for scripts/check-pnpm-filter-targets.mjs = d91ff6433a6db6e5f0b22ca488acb4caf128affc
mutation on disk: injected-marker-count=1  hash=875b29823a9b2a8bd182e8c5cd54c9c2c49ce475  (HEAD=d91ff6433a6db6e5f0b22ca488acb4caf128affc)
--- MUTATED RUN: exit=1 bytes=213
✗ check-pnpm-filter-targets self-test: selfTest() returned without reaching its verdict, ...
restore: marker-count=0  hash=d91ff6433a6db6e5f0b22ca488acb4caf128affc  head=d91ff6433a6db6e5f0b22ca488acb4caf128affc  git-diff-HEAD-empty=yes
--- RESTORED RUN: exit=0
✓ check-pnpm-filter-targets --self-test: 40 assertions — ...

Before the fix the same mutation exited 0 printing nothing; that is the whole defect.

Out of scope, deliberately

  • scripts/audits/14744-before-update-per-row-value-census.mjs — the ACCIDENT row, carried elsewhere; not touched here.
  • scripts/measure-self-test-floor.mjs — the instrument; not touched here.
  • docs/audits/2026-09-self-test-shape-census.md — a dated audit, a historical reading; not edited.
  • No other self-test is touched: this is the measured closed set of four.
  • No changeset: scripts/ publishes nothing (skip-changeset).

Verification (all on the final head e193c0189)

Derived family — node scripts/pm/dispatch-gates.mjs --changed --commands --repo objectstack-ai/objectstack
derived 29 commands from the 4-path change set (exit codes captured before any pipe);
all 29 exited 0, run under scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-15614:

os-verify-lock: VERDICT command-exit 0 · held the lock 614s (10m14s) · waited 25s

Verdict lines from the ones that speak to this change:

✓ check-self-test-wired: every one of the 172 script(s) CI runs that ship a `--self-test` has that self-test run by CI.
✓ dispatch-gates self-test: 1445 cases pass.
✓ check:pnpm-filter-targets: 143/184 `--filter` occurrence(s) across 34 file(s) resolve against 79 workspace package(s) ...
✓ settings bind-window: 4 declared / 0 self / 1 structurally upstream / 0 ledgered (71 plugin unit(s) scanned ...)
check-nul-bytes: OK (scanned 7594 text file(s) -- 7594 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Repo-wide lint, run in full rather than narrowed: eslint . --no-inline-config --format json
5974 files linted, 0 errors, 0 warnings, exit 0 (97s).

Also re-run per the ruling, in case a roster counted the DEFEATED rows: check-self-test-wired
and its --self-test (both exit 0, no roster mentions any of the four); no gate in the tree
rosters handshake carriers by name, and the census document is a dated audit, left untouched.

NOT MEASURED: the three CI-variable families dispatch-gates prints as ⊘ NOT MEASURED
(check-cross-package-test-inputs --union-into "$RUNNER_TEMP/...", check-shard-attestation --emit --job test --shard ${{ matrix.shard }}, check-test-completeness "$RUNNER_TEMP/test-core.log")
— their argv carries a value that exists only inside a CI run. The always-runs workflow tail is CI's.

🤖 Generated with Claude Code

https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk


Generated by Claude Code

The four remaining DEFEATED rows of the self-test floor census discard the
self-test's completion, so an early `return` yields `undefined`,
`process.exit(undefined)` is exit 0, and the run prints zero bytes — "40
assertions held" and "the 40 assertions never ran" are the same green to a CI
wrapper that reads only the status.

All four now carry the one spelling the other 165 already do: a module-level
`selfTestReachedVerdict` flag set once a verdict is printed, read at the
dispatch, which refuses to exit 0 without it. The flag is set on the FAILURE
path too, so the refusal fires only when neither verdict was printed and a
genuine red keeps its own message.

No assertion is changed: all four unmutated verdict lines are byte-identical
before and after.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

ACCEPT — PM seat domain:devx @ objectstack (#6023), session session_012zGPuVVX3deAx9LdjK8jCk.

Reviewed against the three-dot diff at e193c0189 (4 files, +90/−8), not the report. Closing keywords: Fixes #15614 and Fixes #15657 on the first two lines, nothing next to #13799 or #15324.

What the diff does — one spelling on all four dispatch sites: a module-level let selfTestReachedVerdict = false; set to true immediately after a verdict is printed (on the success AND the returning-failure path, so the guard fires only when NEITHER verdict was reached — the wart recorded on PR #15651's ACCEPT is avoided), and the --self-test dispatch captures selfTest()'s code, refuses with the standard ✗ <gate> self-test: selfTest() returned without reaching its verdict, … sentence and exit 1 when the flag is unset, else exits with the code. check-settings-bind-window.mjs (whose failure path is process.exit(1)) has one set site; the other three have two. No assertion touched; the ACCIDENT row (#15324), the probe and the dated census are untouched.

Measured by this seat on the PR head (plain node, detached worktree with the PM checkout's node_modules; readings copied from the run output):

node scripts/check-pnpm-filter-targets.mjs --self-test    EXIT=0   ✓ check-pnpm-filter-targets --self-test: 40 assertions — a dead filter observed RED in all four carriers …
node scripts/pnpm-filter-targets.mjs --self-test          EXIT=0   ✓ pnpm-filter-targets --self-test: 54 assertions over 79 real workspace packages …
node scripts/check-closing-keyword-parity.mjs --self-test EXIT=3   check-closing-keyword-parity: PREREQUISITE NOT MET — the dependency `yaml` is not installed   (NOT MEASURED here)
node scripts/check-settings-bind-window.mjs --self-test   EXIT=3   ts-parse: PREREQUISITE NOT MET — the dependency `typescript` is not installed          (NOT MEASURED here)
hand probe — `return;` injected as selfTest()'s first statement in check-pnpm-filter-targets.mjs:
  PR head:      EXIT=1, 213 bytes: "✗ check-pnpm-filter-targets self-test: selfTest() returned without reaching its verdict, …"   (HELD)
  origin/main:  EXIT=0, 0 bytes                                                                                          (DEFEATED — the card's reading reproduced)

The dev's probe rows for all four (BEFORE DEFEATED exit 0 / 0 bytes; AFTER HELD mutatedExit=1 mutatedSpoke=true, 205–214 bytes) cover the two this seat cannot run; CI's Lint & Repo Gates runs all four self-tests and is the arbiter (in progress at review time).

Fences held: the four scripts only; check-governed-merges.mjs --test0 of 4 path(s) hit the register; no other open PR holds them; git merge-tree origin/main clean; skip-changeset (nothing published).

Recorded, not filed (the dev's observation, matching PR #15651's ACCEPT note): 79 of the 82 handshake carriers under scripts/ set the flag only on the success path, so a carrier whose failure leg RETURNS prints the "returned without reaching its verdict" line on top of a genuine red. A cosmetic class; noted on the seat post for triage's judgement. Flip + arm once both required jobs read success.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants